package com.zhijiang.hospital.service.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhijiang.hospital.entity.dto.FinOpbFeedetailDto;
import com.zhijiang.hospital.entity.dto.PhaComInputDto;
import com.zhijiang.hospital.entity.dto.PhaComOutputDto;
import com.zhijiang.hospital.mapper.FinOpbFeedetailDtoMapper;
import com.zhijiang.hospital.mapper.PhaComInputDtoMapper;
import com.zhijiang.hospital.mapper.PhaComOutputDtoMapper;
import com.zhijiang.hospital.service.FinOpbFeedetailDtoService;
import com.zhijiang.util.BaseQuery;
import com.zhijiang.util.NumberUtils;
import com.zhijiang.util.PageList;
import com.zhijiang.util.TimeUtil;
import com.zhijiang.util.redis.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author 75936
 * @version 1.0
 * @project zhijiang_hospital_data
 * @description
 * @date 2023-02-17 09:39:02
 */
@Service
public class FinOpbFeedetailDtoServiceImpl implements FinOpbFeedetailDtoService {
    @Autowired
    private FinOpbFeedetailDtoMapper finOpbFeedetailDtoMapper;
    @Autowired
    PhaComOutputDtoMapper phaComOutputDtoMapper;
    @Autowired
    PhaComInputDtoMapper phaComInputDtoMapper;
    @Autowired
    RedisService redisService;

    @Override
    public List<FinOpbFeedetailDto> findFinOpbFeedetailDtos(String startTime, String endTime) {
        List<FinOpbFeedetailDto> finOpbFeedetailDtos = finOpbFeedetailDtoMapper.findFinOpbFeedetailDtos(startTime, endTime);
        List<PhaComInputDto> phaComInputDto = phaComInputDtoMapper.findPhaComInputDto(startTime, endTime);
        List<PhaComOutputDto> phaComOutputDto = phaComOutputDtoMapper.findPhaComOutputDto(startTime, endTime);
        List<FinOpbFeedetailDto> collect = finOpbFeedetailDtos.stream().map(m -> {
            phaComInputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setInputNum(m2.getInputNum());
            });
            return m;
        }).collect(Collectors.toList());
        List<FinOpbFeedetailDto> result = collect.stream().map(m -> {
            phaComOutputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setOutPutNum(m2.getOutPutNum());
            });
            return m;
        }).collect(Collectors.toList());
        return result;
    }

    @Override
    public Map<String, Object> findFinOpbFeedetailDtosBaseQuery(BaseQuery baseQuery) {
        List<FinOpbFeedetailDto> finOpbFeedetailDtos = finOpbFeedetailDtoMapper.findFinOpbFeedetailDtos(baseQuery.getStartTime(), baseQuery.getEndTime());
        List<PhaComInputDto> phaComInputDto = phaComInputDtoMapper.findPhaComInputDto(baseQuery.getStartTime(), baseQuery.getEndTime());
        List<PhaComOutputDto> phaComOutputDto = phaComOutputDtoMapper.findPhaComOutputDto(baseQuery.getStartTime(), baseQuery.getEndTime());
        List<FinOpbFeedetailDto> collect = finOpbFeedetailDtos.stream().map(m -> {
            phaComInputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setInputNum(m2.getInputNum());
            });
            return m;
        }).collect(Collectors.toList());
        List<FinOpbFeedetailDto> result = collect.stream().map(m -> {
            phaComOutputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setOutPutNum(m2.getOutPutNum());
            });
            return m;
        }).collect(Collectors.toList());
        List<FinOpbFeedetailDto> collect4 = result.stream().filter(finOpbFeedetailDto -> finOpbFeedetailDto.getOutPutNum() != null).collect(Collectors.toList());
        List<Integer> collect1 = collect4.stream().map(FinOpbFeedetailDto::getOutPutNum).collect(Collectors.toList());
        Integer integer = collect1.stream().reduce(Integer::sum).orElse(0);
        List<FinOpbFeedetailDto> collect5 = result.stream().filter(finOpbFeedetailDto -> finOpbFeedetailDto.getInputNum() != null).collect(Collectors.toList());
        List<Integer> collect2 = collect5.stream().map(FinOpbFeedetailDto::getInputNum).collect(Collectors.toList());
        Integer integer1 = collect2.stream().reduce(Integer::sum).orElse(0);
        List<FinOpbFeedetailDto> collect6 = result.stream().filter(finOpbFeedetailDto -> finOpbFeedetailDto.getPrescriptionNum() != null).collect(Collectors.toList());
        List<String> collect3 = collect6.stream().map(FinOpbFeedetailDto::getPrescriptionNum).collect(Collectors.toList());
        int sum1 = collect3.stream().mapToInt(Integer::parseInt).sum();
        FinOpbFeedetailDto finOpbFeedetailDto = new FinOpbFeedetailDto("合计", String.valueOf(sum1), integer1, integer);
        ArrayList<Object> list1 = new ArrayList<>();
        list1.add(finOpbFeedetailDto);
        Map<String, Object> map = new HashMap<>();
        map.put("heji", list1);
        PageHelper.startPage(baseQuery.getPage(), baseQuery.getPageSize());
        PageInfo<FinOpbFeedetailDto> pageInfo = new PageInfo<>(result);
        Integer pages = NumberUtils.totalPages(pageInfo.getTotal(), baseQuery.getPageSize());
        PageList pageList = new PageList(pageInfo.getTotal(), pageInfo.getList(), baseQuery.getPage(), baseQuery.getPageSize(), pages);
        map.put("jihe", pageList);
        return map;
    }

    @Override
    public List<FinOpbFeedetailDto> loadYearData() {

        DateTime dateTime = DateUtil.beginOfYear(new Date());
        String year = String.valueOf(DateUtil.year(dateTime));
        DateTime dateTime1 = DateUtil.endOfYear(new Date());
        String startTime = Convert.toStr(dateTime);
        String endTime = Convert.toStr(dateTime1);
        if (redisService.hasKey(year + "LoadYearData")) {
            return redisService.getKeyObjectValue(year + "LoadYearData", List.class);
        }
        List<FinOpbFeedetailDto> finOpbFeedetailDtos = finOpbFeedetailDtoMapper.findFinOpbFeedetailDtos(startTime, endTime);
        List<PhaComInputDto> phaComInputDto = phaComInputDtoMapper.findPhaComInputDto(startTime, endTime);
        List<PhaComOutputDto> phaComOutputDto = phaComOutputDtoMapper.findPhaComOutputDto(startTime, endTime);
        List<FinOpbFeedetailDto> collect = finOpbFeedetailDtos.stream().map(m -> {
            phaComInputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setInputNum(m2.getInputNum());
            });
            return m;
        }).collect(Collectors.toList());
        List<FinOpbFeedetailDto> result = collect.stream().map(m -> {
            phaComOutputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setOutPutNum(m2.getOutPutNum());
            });
            return m;
        }).collect(Collectors.toList());
        redisService.setStringKeyAndValue(year + "LoadYearData", result, 1440);
        return result;
    }

    @Override
    public List<FinOpbFeedetailDto> loadLastYearData() {
        Date nextYearPreDay = TimeUtil.getNextYearPreDay();
        DateTime dateTime3 = DateUtil.beginOfYear(nextYearPreDay);
        String year = String.valueOf(DateUtil.year(dateTime3));
        DateTime dateTime4 = DateUtil.endOfYear(nextYearPreDay);
        String startTime = TimeUtil.format(dateTime3);
        String endTime = TimeUtil.format(dateTime4);
        if (redisService.hasKey(year + "LoadLastYearData")) {
            return redisService.getKeyObjectValue(year + "LoadLastYearData", List.class);
        }
        //规定时间内额的处方数量
        List<FinOpbFeedetailDto> finOpbFeedetailDtos = finOpbFeedetailDtoMapper.findFinOpbFeedetailDtos(startTime, endTime);
        //规定时间内的入库数量
        List<PhaComInputDto> phaComInputDto = phaComInputDtoMapper.findPhaComInputDto(startTime, endTime);
        //指定时间内的出库数量
        List<PhaComOutputDto> phaComOutputDto = phaComOutputDtoMapper.findPhaComOutputDto(startTime, endTime);
        List<FinOpbFeedetailDto> collect = finOpbFeedetailDtos.stream().map(m -> {
            phaComInputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setInputNum(m2.getInputNum());
            });
            return m;
        }).collect(Collectors.toList());
        List<FinOpbFeedetailDto> result = collect.stream().map(m -> {
            phaComOutputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setOutPutNum(m2.getOutPutNum());
            });
            return m;
        }).collect(Collectors.toList());
        redisService.setStringKeyAndValue(year + "LoadLastYearData", result, 1440);
        return result;
    }

    @Override
    public Object findBrokenLine(String startTime, String endTime) {
        List<FinOpbFeedetailDto> finOpbFeedetailDtos = finOpbFeedetailDtoMapper.findFinOpbFeedetailDtos(startTime, endTime);
        List<PhaComOutputDto> phaComOutputDto = phaComOutputDtoMapper.findPhaComOutputDto(startTime, endTime);
        List<PhaComInputDto> phaComInputDto = phaComInputDtoMapper.findPhaComInputDto(startTime, endTime);
        List<FinOpbFeedetailDto> collect = finOpbFeedetailDtos.stream().map(m -> {
            phaComInputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setInputNum(m2.getInputNum());
            });
            return m;
        }).collect(Collectors.toList());
        List<FinOpbFeedetailDto> result = collect.stream().map(m -> {
            phaComOutputDto.stream().filter(m2 -> Objects.equals(m.getExecDpnm(), m2.getDeptName())).forEach(m2 -> {
                m.setOutPutNum(m2.getOutPutNum());
            });
            return m;
        }).collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        List<Integer> inPutNumList = new ArrayList<>();
        List<Integer> outPutNumList = new ArrayList<>();
        List<String> deptNameList = new ArrayList<>();
        for (int i = 0; i < result.size(); i++) {
            deptNameList.add(result.get(i).getExecDpnm());
            inPutNumList.add(result.get(i).getInputNum());
            outPutNumList.add(result.get(i).getOutPutNum());
        }
        map.put("deptName", deptNameList);
        map.put("inPutNumList", inPutNumList);
        map.put("outPutNumList", outPutNumList);
        String data = JSON.toJSONString(map);
        return map;
    }
}
